namespace java.io
{
	/// <summary>
	/// A data input stream lets an application read primitive Java data
	/// types from an underlying input stream in a machine-independent
	/// way.
	/// </summary>
	/// <remarks>
	/// A data input stream lets an application read primitive Java data
	/// types from an underlying input stream in a machine-independent
	/// way. An application uses a data output stream to write data that
	/// can later be read by a data input stream.
	/// <p>
	/// DataInputStream is not necessarily safe for multithreaded access.
	/// Thread safety is optional and is the responsibility of users of
	/// methods in this class.
	/// </remarks>
	/// <author>Arthur van Hoff</author>
	/// <version>1.77, 06/07/06</version>
	/// <seealso cref="java.io.DataOutputStream">java.io.DataOutputStream</seealso>
	/// <since>JDK1.0</since>
	public class DataInputStream : FilterInputStream, DataInput
	{
		/// <summary>
		/// Creates a DataInputStream that uses the specified
		/// underlying InputStream.
		/// </summary>
		/// <remarks>
		/// Creates a DataInputStream that uses the specified
		/// underlying InputStream.
		/// </remarks>
		/// <param name="in">the specified input stream</param>
		public DataInputStream(InputStream @in) : base(@in)
		{
		}

		/// <summary>working arrays initialized on demand by readUTF</summary>
		private byte[] bytearr = new byte[80];

		private char[] chararr = new char[80];

		/// <summary>
		/// Reads some number of bytes from the contained input stream and
		/// stores them into the buffer array <code>b</code>.
		/// </summary>
		/// <remarks>
		/// Reads some number of bytes from the contained input stream and
		/// stores them into the buffer array <code>b</code>. The number of
		/// bytes actually read is returned as an integer. This method blocks
		/// until input data is available, end of file is detected, or an
		/// exception is thrown.
		/// <p>If <code>b</code> is null, a <code>NullPointerException</code> is
		/// thrown. If the length of <code>b</code> is zero, then no bytes are
		/// read and <code>0</code> is returned; otherwise, there is an attempt
		/// to read at least one byte. If no byte is available because the
		/// stream is at end of file, the value <code>-1</code> is returned;
		/// otherwise, at least one byte is read and stored into <code>b</code>.
		/// <p>The first byte read is stored into element <code>b[0]</code>, the
		/// next one into <code>b[1]</code>, and so on. The number of bytes read
		/// is, at most, equal to the length of <code>b</code>. Let <code>k</code>
		/// be the number of bytes actually read; these bytes will be stored in
		/// elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
		/// elements <code>b[k]</code> through <code>b[b.length-1]</code>
		/// unaffected.
		/// <p>The <code>read(b)</code> method has the same effect as:
		/// <blockquote><pre>
		/// read(b, 0, b.length)
		/// </pre></blockquote>
		/// </remarks>
		/// <param name="b">the buffer into which the data is read.</param>
		/// <returns>
		/// the total number of bytes read into the buffer, or
		/// <code>-1</code> if there is no more data because the end
		/// of the stream has been reached.
		/// </returns>
		/// <exception>
		/// IOException
		/// if the first byte cannot be read for any reason
		/// other than end of file, the stream has been closed and the underlying
		/// input stream does not support reading after close, or another I/O
		/// error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <seealso cref="java.io.InputStream.read(byte[], int, int)">java.io.InputStream.read(byte[], int, int)
		/// 	</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public sealed override int read(byte[] b)
		{
			return @in.read(b, 0, b.Length);
		}

		/// <summary>
		/// Reads up to <code>len</code> bytes of data from the contained
		/// input stream into an array of bytes.
		/// </summary>
		/// <remarks>
		/// Reads up to <code>len</code> bytes of data from the contained
		/// input stream into an array of bytes.  An attempt is made to read
		/// as many as <code>len</code> bytes, but a smaller number may be read,
		/// possibly zero. The number of bytes actually read is returned as an
		/// integer.
		/// <p> This method blocks until input data is available, end of file is
		/// detected, or an exception is thrown.
		/// <p> If <code>len</code> is zero, then no bytes are read and
		/// <code>0</code> is returned; otherwise, there is an attempt to read at
		/// least one byte. If no byte is available because the stream is at end of
		/// file, the value <code>-1</code> is returned; otherwise, at least one
		/// byte is read and stored into <code>b</code>.
		/// <p> The first byte read is stored into element <code>b[off]</code>, the
		/// next one into <code>b[off+1]</code>, and so on. The number of bytes read
		/// is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
		/// bytes actually read; these bytes will be stored in elements
		/// <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
		/// leaving elements <code>b[off+</code><i>k</i><code>]</code> through
		/// <code>b[off+len-1]</code> unaffected.
		/// <p> In every case, elements <code>b[0]</code> through
		/// <code>b[off]</code> and elements <code>b[off+len]</code> through
		/// <code>b[b.length-1]</code> are unaffected.
		/// </remarks>
		/// <param name="b">the buffer into which the data is read.</param>
		/// <param name="off">the start offset in the destination array <code>b</code></param>
		/// <param name="len">the maximum number of bytes read.</param>
		/// <returns>
		/// the total number of bytes read into the buffer, or
		/// <code>-1</code> if there is no more data because the end
		/// of the stream has been reached.
		/// </returns>
		/// <exception>
		/// NullPointerException
		/// If <code>b</code> is <code>null</code>.
		/// </exception>
		/// <exception>
		/// IndexOutOfBoundsException
		/// If <code>off</code> is negative,
		/// <code>len</code> is negative, or <code>len</code> is greater than
		/// <code>b.length - off</code>
		/// </exception>
		/// <exception>
		/// IOException
		/// if the first byte cannot be read for any reason
		/// other than end of file, the stream has been closed and the underlying
		/// input stream does not support reading after close, or another I/O
		/// error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <seealso cref="java.io.InputStream.read(byte[], int, int)">java.io.InputStream.read(byte[], int, int)
		/// 	</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public sealed override int read(byte[] b, int off, int len)
		{
			return @in.read(b, off, len);
		}

		/// <summary>
		/// See the general contract of the <code>readFully</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readFully</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <param name="b">the buffer into which the data is read.</param>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading all the bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public void readFully(byte[] b)
		{
			readFully(b, 0, b.Length);
		}

		/// <summary>
		/// See the general contract of the <code>readFully</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readFully</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <param name="b">the buffer into which the data is read.</param>
		/// <param name="off">the start offset of the data.</param>
		/// <param name="len">the number of bytes to read.</param>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading all the bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public void readFully(byte[] b, int off, int len)
		{
			if (len < 0)
			{
				throw new System.IndexOutOfRangeException();
			}
			int n = 0;
			while (n < len)
			{
				int count = @in.read(b, off + n, len - n);
				if (count < 0)
				{
					throw new java.io.EOFException();
				}
				n += count;
			}
		}

		/// <summary>
		/// See the general contract of the <code>skipBytes</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>skipBytes</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <param name="n">the number of bytes to be skipped.</param>
		/// <returns>the actual number of bytes skipped.</returns>
		/// <exception>
		/// IOException
		/// if the contained input stream does not support
		/// seek, or the stream has been closed and
		/// the contained input stream does not support
		/// reading after close, or another I/O error occurs.
		/// </exception>
		/// <exception cref="System.IO.IOException"></exception>
		public int skipBytes(int n)
		{
			int total = 0;
			int cur = 0;
			while ((total < n) && ((cur = (int)@in.skip(n - total)) > 0))
			{
				total += cur;
			}
			return total;
		}

		/// <summary>
		/// See the general contract of the <code>readBoolean</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readBoolean</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>the <code>boolean</code> value read.</returns>
		/// <exception>
		/// EOFException
		/// if this input stream has reached the end.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public bool readBoolean()
		{
			int ch = @in.read();
			if (ch < 0)
			{
				throw new java.io.EOFException();
			}
			return (ch != 0);
		}

		/// <summary>
		/// See the general contract of the <code>readByte</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readByte</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next byte of this input stream as a signed 8-bit
		/// <code>byte</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream has reached the end.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public byte readByte()
		{
			int ch = @in.read();
			if (ch < 0)
			{
				throw new java.io.EOFException();
			}
			return (byte)(ch);
		}

		/// <summary>
		/// See the general contract of the <code>readUnsignedByte</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readUnsignedByte</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next byte of this input stream, interpreted as an
		/// unsigned 8-bit number.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream has reached the end.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public int readUnsignedByte()
		{
			int ch = @in.read();
			if (ch < 0)
			{
				throw new java.io.EOFException();
			}
			return ch;
		}

		/// <summary>
		/// See the general contract of the <code>readShort</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readShort</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next two bytes of this input stream, interpreted as a
		/// signed 16-bit number.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading two bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public short readShort()
		{
			int ch1 = @in.read();
			int ch2 = @in.read();
			if ((ch1 | ch2) < 0)
			{
				throw new java.io.EOFException();
			}
			return (short)((ch1 << 8) + (ch2 << 0));
		}

		/// <summary>
		/// See the general contract of the <code>readUnsignedShort</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readUnsignedShort</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next two bytes of this input stream, interpreted as an
		/// unsigned 16-bit integer.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading two bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public int readUnsignedShort()
		{
			int ch1 = @in.read();
			int ch2 = @in.read();
			if ((ch1 | ch2) < 0)
			{
				throw new java.io.EOFException();
			}
			return (ch1 << 8) + (ch2 << 0);
		}

		/// <summary>
		/// See the general contract of the <code>readChar</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readChar</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next two bytes of this input stream, interpreted as a
		/// <code>char</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading two bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public char readChar()
		{
			int ch1 = @in.read();
			int ch2 = @in.read();
			if ((ch1 | ch2) < 0)
			{
				throw new java.io.EOFException();
			}
			return (char)((ch1 << 8) + (ch2 << 0));
		}

		/// <summary>
		/// See the general contract of the <code>readInt</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readInt</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next four bytes of this input stream, interpreted as an
		/// <code>int</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading four bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public int readInt()
		{
			int ch1 = @in.read();
			int ch2 = @in.read();
			int ch3 = @in.read();
			int ch4 = @in.read();
			if ((ch1 | ch2 | ch3 | ch4) < 0)
			{
				throw new java.io.EOFException();
			}
			return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
		}

		private byte[] readBuffer = new byte[8];

		/// <summary>
		/// See the general contract of the <code>readLong</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readLong</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next eight bytes of this input stream, interpreted as a
		/// <code>long</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading eight bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public long readLong()
		{
			readFully(readBuffer, 0, 8);
			return (((long)readBuffer[0] << 56) + ((long)(readBuffer[1] & 255) << 48) + ((long
				)(readBuffer[2] & 255) << 40) + ((long)(readBuffer[3] & 255) << 32) + ((long)(readBuffer
				[4] & 255) << 24) + ((readBuffer[5] & 255) << 16) + ((readBuffer[6] & 255) << 8)
				 + ((readBuffer[7] & 255) << 0));
		}

		/// <summary>
		/// See the general contract of the <code>readFloat</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readFloat</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next four bytes of this input stream, interpreted as a
		/// <code>float</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading four bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.DataInputStream.readInt()">java.io.DataInputStream.readInt()
		/// 	</seealso>
		/// <seealso cref="Sharpen.Runtime.intBitsToFloat(int)">Sharpen.Runtime.intBitsToFloat(int)
		/// 	</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public float readFloat()
		{
            //TODO: Check
			return System.BitConverter.ToSingle(System.BitConverter.GetBytes(readInt()), 0);
		}

		/// <summary>
		/// See the general contract of the <code>readDouble</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readDouble</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>
		/// the next eight bytes of this input stream, interpreted as a
		/// <code>double</code>.
		/// </returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading eight bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.DataInputStream.readLong()">java.io.DataInputStream.readLong()
		/// 	</seealso>
		/// <seealso cref="double.longBitsToDouble(long)">double.longBitsToDouble(long)</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public double readDouble()
		{
            //TODO: Check
            return System.BitConverter.ToDouble(System.BitConverter.GetBytes(readLong()), 0);
		}

		private char[] lineBuffer;

		/// <summary>
		/// See the general contract of the <code>readLine</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readLine</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>the next line of text from this input stream.</returns>
		/// <exception>
		/// IOException
		/// if an I/O error occurs.
		/// </exception>
		/// <seealso cref="java.io.BufferedReader.readLine()">java.io.BufferedReader.readLine()
		/// 	</seealso>
		/// <seealso cref="java.io.FilterInputStream#in">java.io.FilterInputStream#in</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		[System.ObsoleteAttribute(@"This method does not properly convert bytes to characters. As of JDK&nbsp;1.1, the preferred way to read lines of text is via the <code>BufferedReader.readLine()</code> method.  Programs that use the <code>DataInputStream</code> class to read lines can be converted to use the <code>BufferedReader</code> class by replacing code of the form: <blockquote><pre> DataInputStream d =&nbsp;new&nbsp;DataInputStream(in); </pre></blockquote> with: <blockquote><pre> BufferedReader d =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in)); </pre></blockquote>"
			)]
		public string readLine()
		{
			char[] buf = lineBuffer;
			if (buf == null)
			{
				buf = lineBuffer = new char[128];
			}
			int room = buf.Length;
			int offset = 0;
			int c = -1;
			bool flag = true;
			while (flag)
			{
				switch (c = @in.read())
				{
					case -1:
					case '\n':
					{
						flag = false;
						break;
					}

					case '\r':
					{
						int c2 = @in.read();
						if ((c2 != '\n') && (c2 != -1))
						{
							if (!(@in is PushbackInputStream))
							{
								this.@in = new PushbackInputStream(@in);
							}
							((PushbackInputStream)@in).unread(c2);
						}
						flag = false;
						break;
					}

					default:
					{
						if (--room < 0)
						{
							buf = new char[offset + 128];
							room = buf.Length - offset - 1;
							System.Array.Copy(lineBuffer, 0, buf, 0, offset);
							lineBuffer = buf;
						}
						buf[offset++] = (char)c;
						break;
						break;
					}
				}
			}
			if ((c == -1) && (offset == 0))
			{
				return null;
			}
			return new string(buf, 0, offset);
		}

		/// <summary>
		/// See the general contract of the <code>readUTF</code>
		/// method of <code>DataInput</code>.
		/// </summary>
		/// <remarks>
		/// See the general contract of the <code>readUTF</code>
		/// method of <code>DataInput</code>.
		/// <p>
		/// Bytes
		/// for this operation are read from the contained
		/// input stream.
		/// </remarks>
		/// <returns>a Unicode string.</returns>
		/// <exception>
		/// EOFException
		/// if this input stream reaches the end before
		/// reading all the bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <exception>
		/// UTFDataFormatException
		/// if the bytes do not represent a valid
		/// modified UTF-8 encoding of a string.
		/// </exception>
		/// <seealso cref="java.io.DataInputStream.readUTF(java.io.DataInput)">java.io.DataInputStream.readUTF(java.io.DataInput)
		/// 	</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public string readUTF()
		{
			return readUTF(this);
		}

		/// <summary>
		/// Reads from the
		/// stream <code>in</code> a representation
		/// of a Unicode  character string encoded in
		/// <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
		/// this string of characters is then returned as a <code>String</code>.
		/// </summary>
		/// <remarks>
		/// Reads from the
		/// stream <code>in</code> a representation
		/// of a Unicode  character string encoded in
		/// <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
		/// this string of characters is then returned as a <code>String</code>.
		/// The details of the modified UTF-8 representation
		/// are  exactly the same as for the <code>readUTF</code>
		/// method of <code>DataInput</code>.
		/// </remarks>
		/// <param name="in">a data input stream.</param>
		/// <returns>a Unicode string.</returns>
		/// <exception>
		/// EOFException
		/// if the input stream reaches the end
		/// before all the bytes.
		/// </exception>
		/// <exception>
		/// IOException
		/// the stream has been closed and the contained
		/// input stream does not support reading after close, or
		/// another I/O error occurs.
		/// </exception>
		/// <exception>
		/// UTFDataFormatException
		/// if the bytes do not represent a
		/// valid modified UTF-8 encoding of a Unicode string.
		/// </exception>
		/// <seealso cref="java.io.DataInputStream.readUnsignedShort()">java.io.DataInputStream.readUnsignedShort()
		/// 	</seealso>
		/// <exception cref="System.IO.IOException"></exception>
		public static string readUTF(DataInput @in)
		{
			int utflen = @in.readUnsignedShort();
			byte[] bytearr = null;
			char[] chararr = null;
			if (@in is DataInputStream)
			{
				DataInputStream dis = (DataInputStream)@in;
				if (dis.bytearr.Length < utflen)
				{
					dis.bytearr = new byte[utflen * 2];
					dis.chararr = new char[utflen * 2];
				}
				chararr = dis.chararr;
				bytearr = dis.bytearr;
			}
			else
			{
				bytearr = new byte[utflen];
				chararr = new char[utflen];
			}
			int c;
			int char2;
			int char3;
			int count = 0;
			int chararr_count = 0;
			@in.readFully(bytearr, 0, utflen);
			while (count < utflen)
			{
				c = (int)bytearr[count] & unchecked((int)(0xff));
				if (c > 127)
				{
					break;
				}
				count++;
				chararr[chararr_count++] = (char)c;
			}
			while (count < utflen)
			{
				c = (int)bytearr[count] & unchecked((int)(0xff));
				switch (c >> 4)
				{
					case 0:
					case 1:
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
					case 7:
					{
						count++;
						chararr[chararr_count++] = (char)c;
						break;
					}

					case 12:
					case 13:
					{
						count += 2;
						if (count > utflen)
						{
							throw new java.io.UTFDataFormatException("malformed input: partial character at end"
								);
						}
						char2 = (int)bytearr[count - 1];
						if ((char2 & unchecked((int)(0xC0))) != unchecked((int)(0x80)))
						{
							throw new java.io.UTFDataFormatException("malformed input around byte " + count);
						}
						chararr[chararr_count++] = (char)(((c & unchecked((int)(0x1F))) << 6) | (char2 & 
							unchecked((int)(0x3F))));
						break;
					}

					case 14:
					{
						count += 3;
						if (count > utflen)
						{
							throw new java.io.UTFDataFormatException("malformed input: partial character at end"
								);
						}
						char2 = (int)bytearr[count - 2];
						char3 = (int)bytearr[count - 1];
						if (((char2 & unchecked((int)(0xC0))) != unchecked((int)(0x80))) || ((char3 & unchecked(
							(int)(0xC0))) != unchecked((int)(0x80))))
						{
							throw new java.io.UTFDataFormatException("malformed input around byte " + (count 
								- 1));
						}
						chararr[chararr_count++] = (char)(((c & unchecked((int)(0x0F))) << 12) | ((char2 
							& unchecked((int)(0x3F))) << 6) | ((char3 & unchecked((int)(0x3F))) << 0));
						break;
					}

					default:
					{
						throw new java.io.UTFDataFormatException("malformed input around byte " + count);
						break;
					}
				}
			}
			// The number of chars produced may be less than utflen
			return new string(chararr, 0, chararr_count);
		}
	}
}
